package de.szut.impl;

import com.j256.ormlite.dao.BaseDaoImpl;
import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.support.ConnectionSource;
import de.szut.entity.Country;
import de.szut.entity.OperatingSystem;
import de.szut.interfaces.CountryDao;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Created by dzebcuks on 23.08.13.
 */
public class CountryDaoImpl extends BaseDaoImpl<Country, String> implements
        CountryDao, Serializable {

    private List<Country> countries = new ArrayList<Country>();

    /**
     * Must be defined...
     *
     * @param connectionSource
     * @param dataClass
     * @throws java.sql.SQLException
     */
    public CountryDaoImpl(ConnectionSource connectionSource,
                          Class<Country> dataClass) throws SQLException {
        super(connectionSource, Country.class);
    }

    @Override
    public Country getCountryByColor(int color) {
//        // wtf is this shit?
//        Country country = null;
//        QueryBuilder queryBuilder = this.queryBuilder();
//        try {
//            List<Country> countries = this.query(queryBuilder.where().eq(Country.COLUMN_COUNTRY_COLOR, color).prepare());
//            for (Country c : countries) {
//                country = c;
//            }
//        } catch (SQLException e) {
//            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
//        }
        this.loadAllCountries(); // TODO : < delete this line >
        Country country = null;
        QueryBuilder queryBuilder = this.queryBuilder();
        try {
            queryBuilder.where().eq(Country.COLUMN_COUNTRY_COLOR, color);
            country = (Country) queryBuilder.queryForFirst();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return country;
    }

    @Override
    public Country getCountryByName(String name) {
        Country country = null;
        QueryBuilder queryBuilder = this.queryBuilder();
        try {
            queryBuilder.where().eq(Country.COLUMN_COUNTRY_NAME, name);
            country = (Country) queryBuilder.queryForFirst();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return country;
    }

    public void loadAllCountries() {
        if (this.countries.isEmpty()) {
            try {
                this.countries = this.queryForAll();
            } catch (SQLException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        }
    }

    @Override
    public List<Country> getInfectedCountries() {
        if (countries.isEmpty()) {
            this.loadAllCountries();
        }
        List<Country> infectedCountries = new ArrayList<Country>();
        for (Country country : this.countries) {
            int infectedUser = 0;
            for (Iterator<OperatingSystem> it = country.getOperatingSystems().iterator(); it.hasNext(); ) {
                OperatingSystem os = it.next();
                infectedUser += os.getUsers().getInfectedUsers();
            }
            if (infectedUser > 0) {
                infectedCountries.add(country);
            }
        }
        return infectedCountries;
    }

    @Override
    public List<Country> getNotInfectedCountries() {
        if (countries.isEmpty()) {
            this.loadAllCountries();
        }
        List<Country> nonInfectedCountries = new ArrayList<Country>();
        for (Country country : this.countries) {
            int infectedUser = 0;
            for (Iterator<OperatingSystem> it = country.getOperatingSystems().iterator(); it.hasNext(); ) {
                OperatingSystem os = it.next();
                infectedUser += os.getUsers().getInfectedUsers();
            }
            if (infectedUser == 0) {
                nonInfectedCountries.add(country);
            }
        }
        return nonInfectedCountries;
    }

    @Override
    public List<Country> getControlledCountries() {
        this.loadAllCountries();
        List<Country> controlledCountries = new ArrayList<Country>();
        for (Country country : this.countries) {
            int controlledUser = 0;
            int totalUser = 0;
            for (Iterator<OperatingSystem> it = country.getOperatingSystems().iterator(); it.hasNext(); ) {
                OperatingSystem os = it.next();
                controlledUser += os.getUsers().getControlledUsers();
                totalUser += os.getUsers().getTotalUsers();
            }
            if (controlledUser == totalUser) {
                controlledCountries.add(country);
            }
        }
        return controlledCountries;  //To change body of implemented methods use File | Settings | File Templates.
    }

    public List<Country> getCountries() {
        return countries;
    }
}
